package com.casic.ops.entity.dto.pipeline.datastructure.manager;


import com.casic.ops.entity.dto.pipeline.datastructure.loader.PipelineNodeLoader;
import com.casic.ops.runner.pipeline.node.ExecutableNode;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 流水线执行类加载器，该类实现了InitialingBean接口，在程序启动的时候会把节点执行类加载进来，并且按照节点名称为key，节点可执行对象为value
 * @author cww
 * @date 2022/6/17
 */
@Service
public class PipelineNodeManager implements InitializingBean {

    @Resource
    private PipelineNodeLoader pipelineNodeLoader;

    private ConcurrentHashMap<String, ExecutableNode> cached = new ConcurrentHashMap<>(2<<4);

    public void add(String key, ExecutableNode node){
        cached.put(key,node);
    }

    public ExecutableNode get(String key){
        return cached.get(key);
    }

    public ExecutableNode remove(String key){
        return cached.remove(key);
    }

    /**
     * 从这个方法加载的节点执行对象可以看出，运行时一个节点就只有一个对应的执行对象，通过name来获取这个执行对象，后面有新的需求是，一条流水线有2个以上自定义模板，或者以后2个以上的人工卡点或执行命令
     * 等这些可以重复存在的节点，那么此时可能会有并发冲突问题，这个执行类加载器可能被弃用。
     */
    @Override
    public void afterPropertiesSet() {
        pipelineNodeLoader.loadAll().forEach(node -> add(node.getName(),node));
    }
}
